package com.vxdata.utils.modules.utils.security;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * gzip 对字符串压缩和解压缩
 *
 * @author leng
 */
public class GzipStrUtils {


    public static void main(String[] args) throws IOException {
        // 字符串超过一定的长度
        String str = "{\"sgyydl\":\"tempor ut velit officia nostrud\",\"cjsj\":\"dolor ut\",\"tjfs\":\"dolore\",\"sgss\":\"enim dolore voluptate\",\"glxzdj\":\"id eu mollit minim\",\"wd\":\"ullamco consectetur\",\"clmj\":\"ad minim proident dolore Lorem\",\"lm\":\"anim consectetur laboris ad\",\"sgrdyy\":\"tempor amet occaecat dolore consequat\",\"sgdd\":\"veniam non sint et aliquip\",\"xzqh\":\"voluptate proident mollit labore id\",\"tq\":\"ut dolor\",\"sgfssj\":\"voluptate\",\"lddm\":\"sit eiusmod nostrud\",\"clbm\":\"magna irure reprehenderit\",\"userInfoList\":[{\"zjcx\":\"enim Lorem non\",\"sgzr\":\"magna\",\"rylx\":\"dolore\",\"hpzl\":\"magna nulla sit dolore cillum\",\"jszzl\":\"sed adipisicing anim eiusmod tempor\",\"nl\":\"quis laboris\",\"gcxwdl\":\"aute pariatur ullamco incididunt\",\"xb\":\"quis amet\",\"dh\":\"exercitation aute reprehenderit voluptate sit\",\"bxpzh\":\"minim voluptate ullamco do Excepteur\",\"bxgs\":\"sint officia pariatur ut elit\",\"hphm\":\"enim ut do Duis dolor\",\"zz\":\"quis dolor magna\",\"gcxwdx\":\"elit dolor commodo dolor\",\"xm\":\"elit aute\",\"jtfs\":\"proident\",\"sfzmhm\":\"cupidatat\",\"rybh\":\"labore\"},{\"xm\":\"non laboris ex id fugiat\",\"rybh\":\"veniam Ut aliquip\",\"zjcx\":\"consequat\",\"gcxwdx\":\"adipisicing\",\"hpzl\":\"pariatur irure cupidatat\",\"rylx\":\"est laborum veniam ea ad\",\"jszzl\":\"ea ipsum dolor\",\"hphm\":\"pariatur\",\"jtfs\":\"Duis cupidatat\",\"sgzr\":\"ut id\",\"bxgs\":\"nisi non\",\"dh\":\"consequat ea\",\"gcxwdl\":\"consequat tempor ut culpa dolor\",\"zz\":\"occaecat\",\"sfzmhm\":\"elit dolore enim\",\"bxpzh\":\"sunt\",\"nl\":\"adipisicing sunt culpa\",\"xb\":\"nulla Ut labore\"},{\"hphm\":\"aute sint magna\",\"rybh\":\"aliqua incididunt\",\"xm\":\"elit sunt ad\",\"bxgs\":\"mollit\",\"gcxwdl\":\"in id dolor elit irure\",\"bxpzh\":\"aute et\",\"rylx\":\"fugiat adipisicing\",\"xb\":\"id\",\"zz\":\"do pariatur tempor occaecat\",\"jszzl\":\"incididunt\",\"zjcx\":\"culpa\",\"sgzr\":\"reprehenderit irure dolore sint\",\"dh\":\"ullamco culpa adipisicing\",\"hpzl\":\"veniam ipsum\",\"gcxwdx\":\"esse aliqua\",\"nl\":\"magna ea commodo\",\"jtfs\":\"ipsum enim Excepteur\",\"sfzmhm\":\"cupidatat enim consectetur\"},{\"xb\":\"ullamco\",\"sfzmhm\":\"Ut sint in ex\",\"rylx\":\"amet nisi occaecat mollit\",\"dh\":\"reprehenderit in laboris\",\"xm\":\"velit dolor in\",\"jszzl\":\"ullamco est aliqua dolor non\",\"gcxwdx\":\"fugiat aliquip in id officia\",\"sgzr\":\"do nisi\",\"rybh\":\"aliqua culpa\",\"gcxwdl\":\"sit anim proident Ut voluptate\",\"hphm\":\"minim aute tempor ipsum\",\"zz\":\"Ut nulla dolor nostrud\",\"bxpzh\":\"velit\",\"bxgs\":\"consequat aliquip\",\"nl\":\"cillum officia\",\"jtfs\":\"sed proident voluptate ut culpa\",\"zjcx\":\"exercitation nulla Duis eiusmod consequat\",\"hpzl\":\"commodo Lorem sint irure\"},{\"sfzmhm\":\"ex veniam\",\"bxgs\":\"voluptate nostrud enim velit\",\"gcxwdx\":\"ea\",\"dh\":\"in dolore\",\"sgzr\":\"nulla minim deserunt eiusmod\",\"bxpzh\":\"deserunt quis\",\"hpzl\":\"consequat\",\"hphm\":\"non\",\"jszzl\":\"irure ut mollit dolore ut\",\"rylx\":\"anim\",\"xb\":\"quis deserunt\",\"zz\":\"est enim velit officia\",\"gcxwdl\":\"in\",\"zjcx\":\"dolor non qui in\",\"jtfs\":\"proident\",\"xm\":\"in\",\"nl\":\"nulla\",\"rybh\":\"dolore mollit velit enim\"}],\"jafs\":\"ipsum laboris eu velit\",\"sgxt\":\"esse ut voluptate\",\"lh\":\"do\",\"rdsj\":\"eiusmod\",\"ms\":\"magna est in adipisicing tempor\",\"dllx\":\"esse\",\"rdyyfl\":\"tempor Duis\",\"jd\":\"do cillum tempor\",\"sgbh\":\"est dolor in\"}";
        System.out.println("\n原始的字符串为------->" + str);
        float len0 = str.length();
        System.out.println("原始的字符串长度为------->" + len0);

        String ys = compress(str);
        System.out.println("\n压缩后的字符串为----->" + ys);
        float len1 = ys.length();
        System.out.println("压缩后的字符串长度为----->" + len1);

        String jy = unCompress(ys);
        System.out.println("\n解压缩后的字符串为--->" + jy);
        System.out.println("解压缩后的字符串长度为--->" + jy.length());

        System.out.println("\n压缩比例为" + len1 / len0);

        //判断
        if (str.equals(jy)) {
            System.out.println("先压缩再解压以后字符串和原来的是一模一样的");
        }
    }

    /**
     * 字符串的压缩
     *
     * @param str 待压缩的字符串
     * @return 返回压缩后的字符串
     * @throws IOException
     */
    public static String compress(String str) {
        if (str == null || str.isEmpty()) {
            return null;
        }
        // 创建一个新的 byte 数组输出流
        // 使用默认缓冲区大小创建新的输出流
        try (ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(out);) {
            // 将 b.length 个字节写入此输出流
            gzip.write(str.getBytes("utf-8"));
            gzip.close();
            return new String(out.toByteArray(), StandardCharsets.ISO_8859_1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 字符串的解压
     *
     * @param str 对字符串解压
     * @return 返回解压缩后的字符串
     * @throws IOException
     */
    public static String unCompress(String str) {
        if (str == null || str.isEmpty()) {
            return null;
        }
        byte[] buf = str.getBytes(StandardCharsets.ISO_8859_1);
        // 创建一个新的 byte 数组输出流
        try (ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream bais = new ByteArrayInputStream(buf);
             GZIPInputStream gzip = new GZIPInputStream(bais)) {
            byte[] buffer = new byte[4096];
            int n = 0;
            while ((n = gzip.read(buffer)) != -1) {// 将未压缩数据读入字节数组
                // 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte数组输出流
                out.write(buffer, 0, n);
            }
            // 使用指定的 charsetName，通过解码字节将缓冲区内容转换为字符串
            return out.toString("utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}